package com.aydx.minirpc.core;

import com.aydx.minirpc.core.client.RemoteCallCenter;
import com.aydx.minirpc.core.proxy.BeanProxyFactory;
import com.aydx.minirpc.core.register.RpcRegister;
import com.aydx.minirpc.core.register.RegisterCenter;
import com.aydx.minirpc.core.register.ZookeeperRegister;
import com.aydx.minirpc.core.serializable.SerializableFactory;
import com.aydx.minirpc.core.server.AnswerRemoteCall;
import com.aydx.minirpc.core.server.NettyMinirpcServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;

import java.util.ArrayList;
import java.util.List;

/**
 * 上下文
 */
public class MiniRpcContext {
    private Logger logger = LoggerFactory.getLogger(MiniRpcContext.class);
    private RegisterCenter registerCenter;  //注册器
    private RemoteCallCenter remoteCallCenter;  //远程调用客户端
    private BeanProxyFactory beanProxyFactory;  //代理工厂
    private MiniRpcConfig miniRpcConfig;  //配置类
    private NettyMinirpcServer nettyServer;  //服务器
    private AnswerRemoteCall answerRemoteCall;  //远程调用响应器
    private SerializableFactory serializableFactory;  //序列化器

    public static MiniRpcContext newInstance(@NonNull  MiniRpcConfig miniRpcConfig, @NonNull  BeanProxyFactory beanProxyFactory, @NonNull  AnswerRemoteCall answerRemoteCall, @NonNull  SerializableFactory serializableFactory) throws Exception {
        MiniRpcContext rpcContext=new MiniRpcContext(miniRpcConfig,beanProxyFactory,serializableFactory);
        RpcRegister register= ZookeeperRegister.newInstance("default",miniRpcConfig.getRegisterAddress(),100000);
        List<RpcRegister> list=new ArrayList<>();
        list.add(register);
        RegisterCenter registerCenter=RegisterCenter.newInstance(list);
        rpcContext.setRegisterCenter(registerCenter);
        //构建响应器
        answerRemoteCall.setRpcContext(rpcContext);
        rpcContext.setAnswerRemoteCall(answerRemoteCall);
        //构建nettyServer
        NettyMinirpcServer nettyServer=new NettyMinirpcServer(rpcContext);
        rpcContext.setNettyServer(nettyServer);
        //构建远程调用器
        rpcContext.setRemoteCallCenter(new RemoteCallCenter(rpcContext));
        //
        beanProxyFactory.setMiniRpcContext(rpcContext);
        answerRemoteCall.setRpcContext(rpcContext);
        //
        return rpcContext;
    }
    public void startServer(){
        logger.info("开始启动MiniRpc netty服务");
        nettyServer.startServer();
        logger.info("启动MiniRpc netty服务完毕");
    }
    private MiniRpcContext(MiniRpcConfig miniRpcConfig,BeanProxyFactory beanProxyFactory, SerializableFactory serializableFactory) {
        this.miniRpcConfig = miniRpcConfig;
        this.serializableFactory = serializableFactory;
        this.beanProxyFactory = beanProxyFactory;
    }

    public SerializableFactory getSerializableFactory() {
        return serializableFactory;
    }

    public void setSerializableFactory(SerializableFactory serializableFactory) {
        this.serializableFactory = serializableFactory;
    }

    public AnswerRemoteCall getAnswerRemoteCall() {
        return answerRemoteCall;
    }

    public void setAnswerRemoteCall(AnswerRemoteCall answerRemoteCall) {
        this.answerRemoteCall = answerRemoteCall;
    }

    public RegisterCenter getRegisterCenter() {
        return registerCenter;
    }

    public RemoteCallCenter getRemoteCallCenter() {
        return remoteCallCenter;
    }

    public BeanProxyFactory getBeanProxyFactory() {
        return beanProxyFactory;
    }

    public MiniRpcConfig getMiniRpcConfig() {
        return miniRpcConfig;
    }

    public void setRegisterCenter(RegisterCenter registerCenter) {
        this.registerCenter = registerCenter;
    }

    public void setRemoteCallCenter(RemoteCallCenter remoteCallCenter) {
        this.remoteCallCenter = remoteCallCenter;
    }

    public void setBeanProxyFactory(BeanProxyFactory beanProxyFactory) {
        this.beanProxyFactory = beanProxyFactory;
    }

    public void setMiniRpcConfig(MiniRpcConfig miniRpcConfig) {
        this.miniRpcConfig = miniRpcConfig;
    }

    public NettyMinirpcServer getNettyServer() {
        return nettyServer;
    }

    public void setNettyServer(NettyMinirpcServer nettyServer) {
        this.nettyServer = nettyServer;
    }
}
